FADING LIGHTS TUTORIAL

This method for creating fading table lights for Visual Pinball tables is by Eala Dubh. It is inspired, but not based upon, existing methods in Visual PinMAME by PacDude. The VP principles that guide both method will be very close (if not identical) in places however, so there will certainly be similarities between the two. This system is designed to be as easy as possible for the standard VP author to learn and utilise, and is specifically intended for incorporation in non-VPM conversions and original tables.


CONSTRUCTION

First, create a standard VP light array as it would appear normally on your table, encompassing all the lights you require for the game, and name them for use as you would normally do. This will be the first 'layer'. Take a screenshot of your current table with the lights off; this will be used for later reference. Make a list of the lightnames in an easily-remembered order; related groups from the top to the bottom of the table is recommended. Now open the collection manager and group all the lights together according to your list. Each light in the collection must be listed in the correct order for every subsequent layer, matching the positions of those in the first. Add them manually to the collection, instead of by editor selection. Copy and paste all the lights on your table three times to make three subsequent layers, moving them to seperate areas in the editor window for easier organization. Create another collection for each new layer of lights, and ensure you again list each light in the same order as your first layer. (The tutorial table names the collections as LightGrid1, LightGrid2, LightGrid3 and LightGrid4.)

Now you must adjust the colours for the additional light layers. Decide which layer will represent the 'off' lights. The colours for these lights should match those of your first light layer, when those lights are turned off (use your screenshot for reference). This is necessary because in any stack of overlaid lights, the next light to be turned on or off automatically assumes drawing priority (effectively moving to the top of the stack). The easiest way to keep track of the correct light colours is to turn off all lights in the stack, then turn on the one you need. Once your 'off' layer is done, use the colour editor and view the RBG values of your light and dark layers to create two in-between shades for the lights in the remaining two layers.

Create a timer controller (labelled FadeTimer in the tutorial) and set it to the required delay time between each stage of the light fade. PacDude uses a delay time of 40ms for all lights; I prefer less for standard table lights (the tutorial is set to 30ms) as good flashers are much brighter and take longer to fade as a result. Also, for random pattern and/or more rapidly blinking lights displays, a longer delay time may cause the individual lights to spill over into each other, creating a muddier and less discernable display. (Experiment with the tutorial timer.)

Provided you have everything set up correctly, you should be able to start scripting using the basic routines in the tutorial table.


HOW IT WORKS

Each 'stack' of overlaid lights represents four stages of animation, from on through two fade steps to off. the stack needs a corresponding variable to track the current light, in the same way that a reel image keeps a value corresponding to the current frame. Your script must define an array (named LightStatus in the tutorial table) to navigate each of the stack with a different element variable, in the order set up by your collections. Element values follow thus:

LightStatus(f)=3 : light on (Lightgrid1 on)
LightStatus(f)=2 : fade step 1 (Lightgrid2 on)
LightStatus(f)=1 : fade step 2 (Lightgrid3 on)
LightStatus(f)=0 : light off (Lightgrid4 on)

Unlike array variables created in the table script, collection array elements start at zero, not one. Each collection for the tutorial light grid is numbered 0-24, instead of 1-25, and light number (f) will correspond to LightStatus(f-1).

For each light stack on the table, when the brightest (Lightgrid1) light is switched on, the appropriate LightStatus element will be set to 3 during the next CheckStatus call. It will remain at 3 until the brightest light switches from on to off, then will decrease by one for each CheckStatus call, turning on the remaining stacklights in sequence. This will be carried out automatically, with no need for the user to manually manipulate the LightStatus array beyond the first AllLightsInitialise call (when all elements are set to zero). Simply manipulate the lights as you normally would in your VP table, and the code routines should take care of the rest automatically provided you call routine DrawLights after manipulating a light or set of lights. DrawLights affects the redrawing of every light in every stack on the table, and is also called every cycle of the FadeTimer timer. To save CPU time on slow machines, you may want to set up your script to adjust as many lights as is practically possible in one go, and thus call DrawLights as few times outside the FadeTimer cycle as you can.

The PulseTimer routine and timer are used to randomly blink the lights for demonstration purposes, and are not part of the fade script. 


FURTHER APPLICATION

The fading light system will also work for drop-wall lights and reels, using exactly the same timer-controlled principle of operation. For drop-wall lights, create collections in the same manner and simply substitute the '.IsDropped = true/false' command for '.State = LightStateOn/Off' as you normally would. Reels will only require one collection and instead will contain one frame of animation for each layer of the lights, and will depend on manipulating its own reel value instead of multiple true/false commands, in the same manner as for animated flashers.

The main disadvatage to the fading light system is that while the VP engine can easily read the true/false state of a light when LightStateOn or LightStateOff, it cannot determine when LightStateBlinking whether the light is currently lit or unlit within its blink pattern. The fade effects depend on these true/false results to function. With VPM tables the lights are linked to and operated by the emulation engine, and LightStateBlinking never needs to occur. For standard VP tables however, blinking light effects, such as an attract mode display, will have to be programmed and timer-operated manually in the script. Of course, with drop-walls or reels, LightStateBlinking becomes academic anyway. 

Pop bumpers objects, though also affected by the LightStateOn and LightStateOff commands, do not conform to the behaviour of other lights and cannot be used with the fade system. For proper fading pops, you will have to construct reel-based animation images as you would with flashers.

For further information on flashers, fading pops and wall-based fade lights, see PacDude's sterling work on High Speed, Firepower and Fireball II. 